﻿#region legal messages please read
/*
 * 
 * iFinity Software Development - http://www.ifinity.com.au
 * Copyright (c) 2006 - 20011
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
 * documentation files (the "Software"), the rights to use, copy, modify, merge, publish, distribute, sublicense
 * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the 
 * following conditions:

 * 1. The above copyright notice and this permission notice shall be included in all copies or substantial portions 
 *    of the Software.  
 * 2. The software may not be claimed as the original work and may not be sold as a stand alone product

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 * 
 */
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

using DotNetNuke.Entities.Portals;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Modules.Definitions;


/* forum specific references */
using DotNetNuke.Modules.Wiki;

using DotNetNuke.Providers.SearchEngineSiteMapProvider;

namespace DotNetNuke.Providers.SearchEngineSiteMapProvider
{
    public class WikiSiteMapProvider : SiteMapProvider
    {
        private double _maxPagePriority=1.0;
        public WikiSiteMapProvider(string name, System.Collections.Specialized.NameValueCollection config) : base (name, config)
        {
            base.Initialize(name, config);
            _maxPagePriority = GetSafeSetting(config, "maxPagePriority", 1.0);
        }

        public override List<SitePage> SitePagesForTab(DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, DotNetNuke.Entities.Tabs.TabInfo tab, DotNetNuke.Services.Localization.Locale locale, int sitemapNum, int urlCount, int startingCount, int endingCount)
        {
            List<SitePage> wikiUrls = new List<SitePage>();
            //find the forum module(s) on the tab
            base.SetBaseURL(portalAlias.HTTPAlias); //get the base url and portal alias url
            //get the tab, portal and blog information
            if (portalAlias == null)
                throw new Exception("No PortalInfo found for URL (" + _portalAliasURL + ")");
            //635: get the sitemap page priority from the tab if it is avialable
            _defaultPagePriority = GetTabPriority(_defaultPagePriority, tab);
                
            ModuleController modCtl = new ModuleController();
            ModuleDefinitionController modDefs = new ModuleDefinitionController();
            tab.Modules = modCtl.GetPortalTabModules(portalAlias.PortalID, tab.TabID);
            if (tab.Modules != null)
            {
                foreach (ModuleInfo mod in tab.Modules)
                {
                    //check each modeul on the page, looking for the wiki-specific ones
                    List<SitePage> modulePages = new List<SitePage>();
                    ModuleDefinitionInfo modDef = modDefs.GetModuleDefinition(mod.ModuleDefID);
                    string modDefFriendlyName = modDef.FriendlyName;
                    switch (modDefFriendlyName.ToLower())
                    {
                        case "wiki":
                            //get entries for wiki
                            List<SitePage> wikiEntries = GetWikiEntries(mod, tab, locale, sitemapNum, urlCount, startingCount, endingCount);
                            wikiUrls.AddRange(wikiEntries);
                            break;
                    }
                }
            }
            
            return wikiUrls;
        }

        private List<SitePage> GetWikiEntries(ModuleInfo mod, TabInfo tab, DotNetNuke.Services.Localization.Locale locale, int sitemapNum, int urlCount, int startingCount, int endingCount)
        {
            List<SitePage> wikiModuleUrls = new List<SitePage>();
            ChangeFrequencies defaultChangeFreq = SitePage.ConvertChangeFrequencyToEnum(_defaultPageUpdateFrequency);
            int totalRecords = 0;
            double priorityStep = (_maxPagePriority - this.DefaultPagePriority)/10; //there are 10 ratings
            DotNetNuke.Modules.Wiki.Entities.TopicController tc = new DotNetNuke.Modules.Wiki.Entities.TopicController();
            ArrayList topics = tc.GetAllByModuleID(mod.ModuleID);
            foreach (DotNetNuke.Modules.Wiki.Entities.TopicInfo topic in topics)
            {
                if (topic.Name != "WikiHomePage")//don't add an entry for the wikiHomePage topic, to avoid listing twice
                {
                    wikiModuleUrls.Add(BuildTopicSitePageEntry(tab, topic, defaultChangeFreq, priorityStep));
                    totalRecords++;
                }
            }
            return wikiModuleUrls;
        }
        private SitePage BuildTopicSitePageEntry(TabInfo tab, DotNetNuke.Modules.Wiki.Entities.TopicInfo topic, ChangeFrequencies defaultChangeFreq, double priorityStep)
        {
            
            int highestRating = GetHighestTopicRating(topic);
            double priority = this.DefaultPagePriority + (highestRating * priorityStep);
            string url = BuildTopicUrl(tab, topic.Name);
            SitePage wikiSitePage = new SitePage(url, topic.UpdateDate, defaultChangeFreq, priority);
            return wikiSitePage;
        }
/// <summary>
/// Uses the star ratings as a proxy for determining highest priority between topics
/// </summary>
/// <param name="topic"></param>
/// <returns></returns>
        private int GetHighestTopicRating(DotNetNuke.Modules.Wiki.Entities.TopicInfo topic)
        {
            int highestCount = 0;
            int highestRating = 0;
            for (int i = 1; i <= 10; i++)
            {
                switch (i)
                {
                    case 1:
                        if (topic.RatingOneCount >= highestCount)
                            highestRating = 1; highestCount = topic.RatingOneCount;
                        break;
                    case 2:
                        if (topic.RatingTwoCount >= highestCount)
                            highestRating = 2; highestCount = topic.RatingTwoCount;
                        break;
                    case 3:
                        if (topic.RatingThreeCount >= highestCount)
                            highestRating = 3; highestCount = topic.RatingThreeCount;
                        break;
                    case 4:
                        if (topic.RatingFourCount >= highestCount)
                            highestRating = 4; highestCount = topic.RatingFourCount;
                        break;
                    case 5:
                        if (topic.RatingFiveCount >= highestCount)
                            highestRating = 5; highestCount = topic.RatingFiveCount;
                        break;
                    case 6:
                        if (topic.RatingSixCount  >= highestCount)
                            highestRating = 6; highestCount = topic.RatingSixCount;
                        break;
                    case 7:
                        if (topic.RatingSevenCount >= highestCount)
                            highestRating = 7; highestCount = topic.RatingSevenCount ;
                        break;
                    case 8:
                        if (topic.RatingEightCount  >= highestCount)
                            highestRating = 8; highestCount = topic.RatingEightCount;
                        break;
                    case 9:
                        if (topic.RatingNineCount >= highestCount)
                            highestRating = 9; highestCount = topic.RatingNineCount;
                        break;
                    case 10:
                        if (topic.RatingTenCount >= highestCount)
                            highestRating = 10; highestCount = topic.RatingTenCount;
                        break;

                }
            }
            return highestRating;
        }
        /// <summary>
        /// Work out the actual Url used to display a wiki topic
        /// </summary>
        /// <param name="tab"></param>
        /// <param name="topicName"></param>
        /// <returns></returns>
        private string BuildTopicUrl(TabInfo tab, string topicName)
        {
            string url;
            //wiki module uses httpUtility.UrlEncode
            string urlValue = System.Web.HttpUtility.UrlEncode(topicName);
            //and topic=topic+name for the topic
            url = DotNetNuke.Common.Globals.NavigateURL(tab.TabID, "", "topic=" + urlValue);
            return url;
        }
    }
}
